/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


#include "gamelib.h"


odBounds	bounds_zero(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);


/*
 ==================
 odBounds::GetCenter
 ==================
*/
odVec3 odBounds::GetCenter (void) const {

	return odVec3((b[0] + b[1]) * 0.5f);
}

/*
 ==================
 odBounds::GetRadius
 ==================
*/
float odBounds::GetRadius (void) const {

	float	min, max;
	float	radius = 0.0f;
	int		i;

	for (i = 0; i < 3; i++){
		min = M_Fabs(b[0][i]);
		max = M_Fabs(b[1][i]);

		if (min > max)
			radius += (min * min);
		else
			radius += (max * max);
	}

	return M_Sqrt(radius);
}

/*
 ==================
 odBounds::ToSphere
 ==================
*/
void odBounds::ToSphere (odVec3 &center, float *radius) const {

	float	min, max;
	int		i;

	center = (b[0] + b[1]) * 0.5f;

	*radius = 0.0f;

	for (i = 0; i < 3; i++){
		min = M_Fabs(b[0][i]);
		max = M_Fabs(b[1][i]);

		if (min > max)
			*radius += (min * min);
		else
			*radius += (max * max);
	}

	*radius = M_Sqrt(*radius);
}

/*
 ==================
 odBounds::FromSphere
 ==================
*/
void odBounds::FromSphere (const odVec3 &center, float radius){

	b[0][0] = center[0] - radius;
	b[0][1] = center[1] - radius;
	b[0][2] = center[2] - radius;
	b[1][0] = center[0] + radius;
	b[1][1] = center[1] + radius;
	b[1][2] = center[2] + radius;
}

/*
 ==================
 odBounds::ToPoints
 ==================
*/
void odBounds::ToPoints (odVec3 points[8]) const {

	int		i;

	for (i = 0; i < 8; i++){
		points[i][0] = (i & 1) ? b[0][0] : b[1][0];
		points[i][1] = (i & 2) ? b[0][1] : b[1][1];
		points[i][2] = (i & 4) ? b[0][2] : b[1][2];
	}
}

/*
 ==================
 odBounds::FromPoints
 ==================
*/
void odBounds::FromPoints (const odVec3 points[8]){

	int		i;

	b[0][0] = b[0][1] = b[0][2] = M_INFINITY;
	b[1][0] = b[1][1] = b[1][2] = -M_INFINITY;

	for (i = 0; i < 8; i++){
		if (points[i][0] < b[0][0])
			b[0][0] = points[i][0];
		if (points[i][0] > b[1][0])
			b[1][0] = points[i][0];

		if (points[i][1] < b[0][1])
			b[0][1] = points[i][1];
		if (points[i][1] > b[1][1])
			b[1][1] = points[i][1];

		if (points[i][2] < b[0][2])
			b[0][2] = points[i][2];
		if (points[i][2] > b[1][2])
			b[1][2] = points[i][2];
	}
}

/*
 ==================
 odBounds::ToString

 This is just a convenience function for printing bounds
 ==================
*/
const char *odBounds::ToString (int precision) const {

	return Str_FromFloatArray(ToFloatPtr(), 6, precision);
}
